﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Threading;
using System.Reflection;
using eeenno.ReaderEngine.Adapters;
using eeenno.ReaderEngine;
using eeenno.ReaderEngine.Objects;
using eeenno.ReaderEngine.Utilities;

namespace eeenno.ReaderEngine
{
    public static class SpeeedReader
    {
        private static string[] _tag_list = null;
        private static string[] _subscription_list = null;
        private static string[] _unread_count_list = null;

        private static Tags _tags = null;
        private static Articles _reading_list_articles = null;
        private static Articles _starred_articles = null;
        private static Articles _shared_articles = null;
        private static Articles _search_results = null;

        public static Articles search_results
        {
            get { return _search_results; }
            set { _search_results = value; }
        }

        public static Tags tags
        {
            get { return _tags; }
        }

        public static Articles reading
        {
            get { return _reading_list_articles; }
        }

        public static Articles starred
        {
            get { return _starred_articles; }
        }

        public static Articles shared
        {
            get { return _shared_articles; }
        }

        public static void InitializeStorageCardPath()
        {
            CacheEngine.InitializeStorageCardPath();
        }

        public static bool Login(string[] credentials)
        {            
            try
            {
                GoogleReaderEngine.Connect(credentials[0], credentials[1]);
            }
            catch (WebException e)
            {
                LogManager.LogError("SpeeedReader.Login", e.Message);
                return false;
            }
            return GoogleReaderEngine.is_connected;
        }

        public static void CacheData()
        {
            if (Settings.caching_enabled)
            {
                CacheEngine.CacheData(ref _tags);               
            }
        }

        public static bool PopulateLists()
        {
            //if in offline mode
            if (Settings.offline_mode_enabled)
            {
                _tags = CacheEngine.LoadTags();
                return true;
            }
            //if not in offline mode
            else
            {
                Thread sub_thread = ThreadFactory.GetThread("ProcessSubscription", ProcessSubscription);
                Thread tag_thread = ThreadFactory.GetThread("ProcessTags", ProcessTagList);
                Thread unread_thread = ThreadFactory.GetThread("ProcessUnreadCounts", ProcessUnreadCounts);
                sub_thread.Start();
                tag_thread.Start();
                unread_thread.Start();
                sub_thread.Join();
                tag_thread.Join();
                unread_thread.Join();

                if (_subscription_list.Length > 0 && _tag_list.Length > 0)
                {
                    _tags = new Tags(_tag_list, _subscription_list, _unread_count_list);
                    _tag_list = null;
                    _subscription_list = null;
                    _unread_count_list = null;
                    return true;
                }
                _reading_list_articles = SpeeedReader.GetReadingList(Settings.download_size);
                _starred_articles = SpeeedReader.GetArticlesByState("starred");
                _shared_articles = SpeeedReader.GetArticlesByState("broadcast");
            }

            return false;
        }

        private static void ProcessSubscription()
        {
            try
            {
                _subscription_list = XmlEngine.ProcessSubscriptionList(GoogleReaderEngine.GetSubscriptionList());
            }
            catch (Exception e)
            {
                _subscription_list = new string[0];
                LogManager.LogError("SpeeedReader.ProcessSubscription", e.ToString());
            }
        }

        private static void ProcessTagList()
        {
            try
            {
                _tag_list = XmlEngine.ProcessTagList(GoogleReaderEngine.GetTagList());
            }
            catch (Exception e)
            {
                _tag_list = new string[0];
                LogManager.LogError("SpeeedReader.ProcessTagList", e.ToString());
            }
        }

        private static void ProcessUnreadCounts()
        {
            try
            {
                _unread_count_list = XmlEngine.ProcessUnreadCounts(GoogleReaderEngine.GetUnreadCount());
            }
            catch (Exception e)
            {
                _unread_count_list = new string[0];
                LogManager.LogError("SpeeedReader.ProcessUnreadCounts", e.ToString());
            }
        }

        public static void RefreshReadingList(bool first_refresh_run)
        {
            Articles articles = SpeeedReader.GetReadingList(Settings.download_size);
            if (articles != null)
            {
                _reading_list_articles = articles;
            }
        }

        public static void RefreshStarredList()
        {
            Articles articles = SpeeedReader.GetArticlesByState("starred");
            if (articles != null)
            {
                _starred_articles = articles;
            }
        }

        public static void RefreshSharedList()
        {
            Articles articles = SpeeedReader.GetArticlesByState("broadcast");
            if (articles != null)
            {
                _shared_articles = articles;
            }
        }

        public static Subscription ImportSubscription(string name)
        {
            return CacheEngine.ImportSubscription(name);
        }

        public static string CacheSize()
        {
            if (CacheEngine.DoesCacheExist())
            {
                double size = (double)(CacheEngine.GetCacheSize() / 1024) / 1024;
                return size.ToString("0.00") + "MB";
            }
            else
            {
                return "0.00MB";
            }           
        }

        public static bool EmptyCache()
        {
            return CacheEngine.EmptyCache();
        }

        public static bool CopyCache(string source)
        {
            return CacheEngine.CopyCache(source, Settings.cache_path + Settings.username);
        }

        public static Articles GetReadingList(int quantity)
        {
            return new Articles(AtomEngine.ProcessFeedData(
                GoogleReaderEngine.GetArticlesByState("reading-list", quantity)));
        }

        public static Articles GetArticlesByFeed(string feed, int quantity)
        {
            return new Articles(AtomEngine.ProcessFeedData(
                GoogleReaderEngine.GetArticlesByFeed(feed, quantity)));
        }

        public static Article GetArticleByID(string ID)
        {
            return _tags.GetArticleByID(ID);
        }

        public static Articles GetArticleByTag(string tag)
        {
            return new Articles(AtomEngine.ProcessFeedData(
                GoogleReaderEngine.GetArticlesByTag(tag,Settings.download_size)));
        }

        public static Articles GetArticlesByTag(string tag, int quantity)
        {
            return new Articles(AtomEngine.ProcessFeedData(
                GoogleReaderEngine.GetArticlesByTag(tag, quantity)));
        }

        public static Articles GetArticlesByTag(string tag, string timestamp)
        {
            return new Articles(AtomEngine.ProcessFeedData(
                GoogleReaderEngine.GetArticlesByTag(tag, timestamp)));
        }

        public static Articles GetArticlesByState(string state)
        {
            return new Articles(AtomEngine.ProcessFeedData(
                GoogleReaderEngine.GetArticlesByState(state, Settings.download_size)));      
        }

        public static Articles GetMoreFeedArticles(string continuation, string feed)
        {
            return new Articles(AtomEngine.ProcessFeedData(
                GoogleReaderEngine.GetMoreFeedArticles(continuation, feed, Settings.download_size)));
        }

        public static Articles GetMoreTagArticles(string continuation, string tag)
        {
            return new Articles(AtomEngine.ProcessFeedData(
                GoogleReaderEngine.GetMoreTagArticles(continuation, tag, Settings.download_size)));
        }

        /// <summary>
        /// Returns articles after the given timestamp
        /// </summary>
        /// <param name="feed"></param>
        /// <param name="timestamp"></param>
        /// <returns></returns>
        public static Articles GetArticlesByTimestamp(string feed, string timestamp)
        {
            return new Articles(AtomEngine.ProcessFeedData(
                GoogleReaderEngine.GetFeedData(feed, timestamp)));
        }

        public static void MarkArticleUnread(object stateInfo)        
        { 
            GoogleReaderEngine.MarkArticleUnread((string)stateInfo);
        }

        /// <summary>
        /// Stars an item
        /// </summary>
        /// <param name="item_id"></param>
        public static void MarkItemStarred(object item_id)
        {
            GoogleReaderEngine.MarkArticleStarred((string)item_id);
        }

        /// <summary>
        /// Stars an item
        /// </summary>
        /// <param name="item_id"></param>
        public static void MarkItemBroadcast(object item_id)
        {
            GoogleReaderEngine.MarkArticleBroadcast((string)item_id);
        }

        /// <summary>
        /// Marks an Item Read
        /// </summary>
        /// <param name="item_id"></param>
        public static void MarkItemRead(string item_id)
        {
            GoogleReaderEngine.MarkArticleRead(item_id);
        }

        /// <summary>
        /// Marks a subscription (all of its articles) as read
        /// </summary>
        /// <param name="subscription_id"></param>
        public static void MarkAllAsRead(string id, string title)
        {
            if (id != XmlEngine._NO_TAG_KEYWORD)
            {
                GoogleReaderEngine.MarkAllAsRead(id, title);
            }
        }

        public static string MajorVersion()
        {
            return Assembly.GetExecutingAssembly().GetName().Version.Major.ToString();
        }

        public static string MinorVersion()
        {
            return Assembly.GetExecutingAssembly().GetName().Version.Minor.ToString();
        }

        public static string BuildVersion()
        {
            return Assembly.GetExecutingAssembly().GetName().Version.Build.ToString();
        }

        public static void SetCredentials()
        {
            GoogleReaderEngine.username = Settings.username;
            GoogleReaderEngine.password = Settings.password;
        }

        public static bool DoesCacheExist()
        {
            return CacheEngine.DoesCacheExist();
        }
    }
}
